<?php
namespace app\apijson\query\operators;

use Illuminate\Database\Capsule\Manager as DB;

class ColumnOperator
{
    protected static array $aliasMapStore = [];

    public static function apply($query, $value)
    {
        $columns = [];
        $aliasMap = [];
        // 允许的 SQL 聚合函数白名单
        $allowedFuncs = ['max', 'min', 'sum', 'avg', 'count'];
        
        foreach (explode(',', $value) as $col) {
            $col = trim($col);
            if (strpos($col, ':') !== false) {
                [$field, $alias] = explode(':', $col, 2);
                // 检查是否为 SQL 函数
                if (preg_match('/^([a-zA-Z_][a-zA-Z0-9_]*)\\((.+)\\)$/', $field, $fm)) {
                    $func = strtolower($fm[1]);
                    $arg = $fm[2];
                    // 只允许白名单函数和安全字段
                    if (in_array($func, $allowedFuncs) && preg_match('/^[a-zA-Z0-9_.*]+$/', $arg)) {
                        $columns[] = DB::raw("$func($arg) as $alias");
                    } else {
                        throw new \app\apijson\core\ApiJsonException('非法 SQL 函数或字段: ' . $field);
                    }
                } else if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $field)) {
                    // 普通字段
                    $columns[] = $field . ' as ' . $alias;
                } else {
                    throw new \app\apijson\core\ApiJsonException('非法字段名: ' . $field);
                }
                $aliasMap[$field] = $alias;
            } else {
                // SQL 函数无别名时也支持
                if (preg_match('/^([a-zA-Z_][a-zA-Z0-9_]*)\\((.+)\\)$/', $col, $fm)) {
                    $func = strtolower($fm[1]);
                    $arg = $fm[2];
                    if (in_array($func, $allowedFuncs) && preg_match('/^[a-zA-Z0-9_.*]+$/', $arg)) {
                        $columns[] = DB::raw("$func($arg)");
                    } else {
                        throw new \app\apijson\core\ApiJsonException('非法 SQL 函数或字段: ' . $col);
                    }
                } else if (preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $col)) {
                    $columns[] = $col;
                } else {
                    throw new \app\apijson\core\ApiJsonException('非法字段名: ' . $col);
                }
            }
        }
        
        $query->select($columns);
        // 用对象id存储别名映射，避免动态属性
        self::$aliasMapStore[spl_object_id($query)] = $aliasMap;
    }

    public static function getAliasMap($query)
    {
        return self::$aliasMapStore[spl_object_id($query)] ?? [];
    }
} 